package com.googlecode.kipler.syntax.concept;

import com.googlecode.kipler.common.Copyable;

/**
 * The basic concept expression, i.e., a concept name.
 * 
 * @author İnanç Seylan
 * 
 */
public class ConceptName extends Concept {

	private boolean negated;

	/**
	 * The name of this concept
	 */
	private String name;

	/**
	 * Default constructor
	 */
	public ConceptName() {

	}

	/**
	 * Constructor to set the name field
	 * 
	 * @param name
	 *            The concept name to be set
	 */
	public ConceptName(String name) {
		setName(name);
	}

	/**
	 * @return the name of this concept.
	 */
	public String getName() {
		return name.toString();
	}

	/**
	 * Sets the name of this concept.
	 * 
	 * @param name
	 *            The name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return true both concepts have the same name and negation status.
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj != null && (obj.getClass().equals(this.getClass()))) {
			ConceptName other = (ConceptName) obj;
			return (this.isNegated() == other.isNegated()
					&& this.isLeftBiased() == other.isLeftBiased() && this.name
					.equals(other.name));
		}
		return false;
	}

	/**
	 * @see Object#hashCode()
	 */
	@Override
	public int hashCode() {
		return 17 * 37 + new Boolean(negated).hashCode()
				+ new Boolean(isLeftBiased()).hashCode() + name.hashCode();
	}

	/**
	 * Calls {@link ConceptVisitor#visitConceptName(ConceptName)}
	 * 
	 * @see tr.edu.ege.seagent.alcbi.syntax.description.VisitableConcept#accept(tr.edu.ege.seagent.alcbi.syntax.description.ConceptVisitor)
	 */
	public void accept(ConceptVisitor v) {
		v.visitConceptName(this);
	}

	/**
	 * @return true if this concept expression has a negation sign in front of
	 *         it.
	 */
	public boolean isNegated() {
		return negated;
	}

	/**
	 * Toggles the value of negated field.
	 */
	public ConceptName toggleNegated() {
		negated = !negated;
		return this;
	}

	/**
	 * @see Copyable#copy()
	 */
	public ConceptName copy() {
		ConceptName result = new ConceptName();
		result.name = name;
		result.negated = negated;
		result.setLeftBiased(isLeftBiased());
		return result;
	}

	/**
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return (isNegated() ? "~(" + name + ")" : name);
	}
}
